package com.wei.czz.common.utils;

import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.exception.CzzException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2023-11-02 18:16:27
 * className: SpringELUtils SpringEL工具类
 * version: 1.0
 * description:
 */
public class SpringELUtils {

    private static final Logger log = LoggerFactory.getLogger(SpringELUtils.class);

    /**
     * 解析SpringEL语句
     * @param expression 语句
     * @param paramMap   参数映射
     * @param tClass     泛型类型class对象
     * @return 解析结果
     * @param <T> 泛型类型
     */
    public static <T> T execute(String expression, Map<String, Object> paramMap, Class<T> tClass) {
        log.info("SpringEL表达式执行：expression={} paramsMap={}", expression, paramMap);
        // SpringEL语句解析器
        ExpressionParser parser = new SpelExpressionParser();
        // SpringEL上下文
        EvaluationContext ctx = new StandardEvaluationContext();

        // 参数放入ctx上下文中
        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
            ctx.setVariable(entry.getKey(), entry.getValue());
        }

        try {
            // 解析SpringEL语句
            T value = parser.parseExpression(expression).getValue(ctx, tClass);
            log.info("SpringEL表达式执行结果：{}", value);
            return value;
        } catch (ParseException e) {
            log.error("SpringEl语句解析异常。expression={} message={}", expression, e.getMessage(), e);
            throw new CzzException(ResultEnum.SERVICE_FAIL);
        } catch (EvaluationException e) {
            log.error("SpringEl语句生成异常。expression={} message={}", expression, e.getMessage(), e);
            throw new CzzException(ResultEnum.SERVICE_FAIL);
        }
    }

}
